package com.jroky.base.service.impl;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.jroky.base.mapper.BaseMapper;
import com.jroky.base.service.BaseService;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;

@Slf4j
public class BaseServiceImpl<D extends BaseMapper<T>,T> extends MPJBaseServiceImpl<D, T> implements BaseService<T> {

    @Override
    public List<T> dataList(T entity) {
        return this.listDeep(buildQueryWrapper(entity));
    }


    @Override
    public PageInfo<T> pageList(PageInfo pageInfo, T entity) {
        try {
            PageHelper.startPage(pageInfo.getPageNum(),pageInfo.getPageSize());
            return new PageInfo<>(dataList(entity));
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("分页查询异常");
        }
    }

    @Override
    public List<T> fullSave(T o, List<T> list) {
        fullSavePreMethod(o,list);
        cusRemove(o);
        this.saveBatch(list);
        return list;
    }

    private void cusRemove(T o) {
        try {
            this.remove(buildQueryWrapper(o));
        }catch (Exception e){
            throw new RuntimeException("全量保存前删除异常");
        }
    }

    private void fullSavePreMethod(T o, List<T> list) {
    }

    @Override
    public void fullImportByExcel(HttpServletResponse response, MultipartFile file, T entity) {
        // todo
    }

    @Override
    public void exportTemplateExcel(HttpServletRequest request, HttpServletResponse response, String fileName, Class<T> clz) {
        // todo
    }

    private <T> QueryWrapper<T> buildQueryWrapper(T entity) {
        QueryWrapper<T> queryWrapper=new QueryWrapper<>();
        Class<?> calzz = entity.getClass();
        try {
            for (Field field : calzz.getDeclaredFields()){
                if (!field.isAccessible()&&field.getName().startsWith("this$")){
                    continue;
                }
                if (!field.isAccessible()){
                    field.setAccessible(true);
                }

                Object value = field.get(entity);
                if (value != null && !(field.getType() == String.class && ((String) value).isEmpty()) && !ignoreKeys.contains(field.getName())){
                    String columnName = field.getName();
                    if (field.isAnnotationPresent(TableField.class)){
                        TableField tableField = field.getAnnotation(TableField.class);
                        columnName = tableField.value();
                    }else {
                        columnName = camelToUnderline(columnName);
                    }
                    queryWrapper.eq(columnName, value);
                }
            }
        }catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return queryWrapper;
    }

    private String camelToUnderline(String param) {
        if (param == null || param.isEmpty()){
            return "";
        }
        int len = param.length();
        StringBuilder result = new StringBuilder(len * 2);
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c)){
                result.append("_").append(Character.toLowerCase(c));
            }else {
                result.append(c);
            }
        }
        return result.toString();
    }

    protected List<String> ignoreKeys = Arrays.asList(
            "serialVersionUID","INVALID","EFFECTIVE","EXISTED","DELETED","sortName","sortType","like"
    );
}



